#!/usr/bin/env python3
import libtorrent as lt
import sys
import time
from os import get_terminal_size
from string import hexdigits

##magnet_string = 'magnet:?xt=urn:btih:fef84077088ca87ffd8afd644d0ef957d96243c3&dn=archlinux-2023.01.01-x86_64.iso'

try:
  if len(sys.argv[1]) == 40 and all(c in hexdigits for c in sys.argv[1]):
    magnet_string = 'magnet:?xt=urn:btih:' + sys.argv[1]
  else:
    assert sys.argv[1][0:8] == 'magnet:?'
    magnet_string = sys.argv[1]
except:
  print("please provide a magnet link in quotes or a 40 character hex hash as the only arguement")
  print("Example: ", sys.argv[0], '"magnet:?xt=urn:btih:fef84077088ca87ffd8afd644d0ef957d96243c3"')
  print("Example: ", sys.argv[0], "fef84077088ca87ffd8afd644d0ef957d96243c3")
  sys.exit(1)

ses = lt.session({'listen_interfaces': '0.0.0.0:6881'})
params = lt.parse_magnet_uri(magnet_string)
params.save_path = '.'
handle = ses.add_torrent(params)
status = handle.status()

print('\nResolving: ', magnet_string, end=" ", flush=True)
while (not status.name):
  status = handle.status()
  time.sleep(1)
  print('.', end=" ", flush=True)
print('\n\nStarting:', status.name, '\n')

while (not status.is_seeding):
  status = handle.status()
  display = " {:.2f}% complete (down: {:.1f} kB/s up: {:.1f} kB/s peers: {:d}) {}".format(
    status.progress * 100,
    status.download_rate / 1000,
    status.upload_rate / 1000,
    status.num_peers,
    status.state
  )
  columns, rows = get_terminal_size(0)

  if sys.stdout.isatty():
    if columns < len(display):
      display = display[0:columns-1] + '\r'
    else:
      padding_size = columns - len(display) - 1
      padding = " " * padding_size
      display = display + padding + '\r'
  else:
    display = display + "\n"

  print(display, end="")

  alerts = ses.pop_alerts()
  for a in alerts:
    if a.category() & lt.alert.category_t.error_notification:
      print('\nERROR:', a, '\n')
  sys.stdout.flush()
  time.sleep(1)

print("\n\nCompleted: ", status.name, "\n")
